#include "Restorer.h"
extern mutex queue_mutex[10];

Restorer::Restorer(QObject *parent) : QObject(parent) {
}

void Restorer::receive(queue<FrameData> * _frame_data, queue<unsigned char*> * _spe_frame_data, queue<unsigned char*> * _spe_frame_merge_data, char * _code, int _device_num) {
	frame_data = _frame_data;
	spe_frame_data = _spe_frame_data;
	spe_frame_merge_data = _spe_frame_merge_data;
	code = _code;
	device_num = _device_num;
	gpu_restorer = new GpuSpeRestorer(code, rawinfo.know_point_number, 2, rawinfo.OUT_rows, rawinfo.OUT_cols, rawinfo.channel, rawinfo.window_width,rawinfo.window_higth, device_num);
	require_flag = true;
}


void Restorer::restore() {
	if (!require_flag)
		return;
	int index = 0;
	clock_t start, end;
	start = clock();
	while (continue_signal)
	{
		queue_mutex[2 + device_num].lock();
		bool is_frame_data_empty = frame_data->empty();
		queue_mutex[2 + device_num].unlock();
		if (!is_frame_data_empty) {
			//gpu_restorer->generateFrame2(frame_data->front().rgb_data, frame_data->front().spe_data);
			//gpu_restorer->getIndex(index);
			queue_mutex[2 + device_num].lock();
			unsigned char *frame_rgb_data = frame_data->front().rgb_data;
			unsigned char *frame_spe_data = frame_data->front().spe_data;
			queue_mutex[2 + device_num].unlock();
			unsigned char * outdata = new unsigned char[rawinfo.OUT_rows*rawinfo.OUT_rows * rawinfo.channel*2];
			unsigned char * merge_outdata = new unsigned char[rawinfo.merged_rows*rawinfo.merged_cols];
			gpu_restorer->restoreToBuffer(frame_rgb_data, frame_spe_data, outdata, merge_outdata);
			//gpu_restorer->restore();
			
			cudaThreadSynchronize();
			delete[] frame_rgb_data;
			delete[] frame_spe_data;

			queue_mutex[2 + device_num].lock();
			frame_data->pop();
			queue_mutex[2 + device_num].unlock();

			queue_mutex[4 + device_num].lock();
			spe_frame_data->push(outdata);
			queue_mutex[4 + device_num].unlock();

			queue_mutex[6 + device_num].lock();
			spe_frame_merge_data->push(merge_outdata);
			queue_mutex[6 + device_num].unlock();

			index++;
			if (index == 40) {
				end = clock();
				float frame_rate = 80.0 / ((double)(end - start) / CLOCKS_PER_SEC);
				emit sendFrameRate(frame_rate);
				start = clock();
				index = 0;
			}
			emit dataReady(device_num);


		}
	}
}

Restorer::~Restorer() {
	delete gpu_restorer;
}